package com.tongji.housediy.view.components
{
	import com.tongji.housediy.events.commonEvent.CursorBitmapEvent;
	import com.tongji.housediy.events.commonEvent.MouseEnabledAdminEvent;
	import com.tongji.housediy.events.commonEvent.RelatedRoomAdminEvent;
	import com.tongji.housediy.events.commonEvent.RoomNameAdminEvent;
	import com.tongji.housediy.events.commonEvent.RotationRelatedEvent;
	import com.tongji.housediy.events.commonEvent.RulerAdminEvent;
	import com.tongji.housediy.events.commonEvent.SetCompStateEvent;
	import com.tongji.housediy.events.commonEvent.ShowHideFilterEvent;
	import com.tongji.housediy.events.commonEvent.ShowHideTitleWindowEvent;
	import com.tongji.housediy.events.commonEvent.ShowVertexEvent;
	import com.tongji.housediy.utils.AbsorptionDetection;
	import com.tongji.housediy.utils.CollisionDetection;
	import com.tongji.housediy.utils.ConstVariableInventory;
	import com.tongji.housediy.utils.MathCalculation;
	import com.tongji.housediy.vo.Goods;
	import com.tongji.housediy.vo.PicModel;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.CapsStyle;
	import flash.display.GraphicsPath;
	import flash.display.GraphicsPathCommand;
	import flash.display.GraphicsSolidFill;
	import flash.display.GraphicsStroke;
	import flash.display.IGraphicsData;
	import flash.display.JointStyle;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.ui.Mouse;
	
	import mx.controls.Alert;
	import mx.core.IUIComponent;
	import mx.core.UIComponent;
	import mx.events.DragEvent;
	import mx.managers.DragManager;
	
	import spark.components.TextInput;
	import spark.filters.GlowFilter;
	
	/**
	 * 这个类用来绘制 边框，继承自 RoomShape
	 * @author chenchao
	 * 
	 */	
	public class RoomBorder extends RoomShape
	{
		public var removeChildVector:Vector.<AbstractBorderChild> = new Vector.<AbstractBorderChild>();
		
		private var graphicsData:Vector.<IGraphicsData>;
		private var stroke:GraphicsStroke;
		private var commands:Vector.<int>;
		
		public var wallMap:BitmapData;
		public var skirtingMap:BitmapData;
		
		// 是否是弧形边框
		public var isCurve:Boolean;
		
		// 斜率
		public var k:Number;
		
		private var collisionCount:int = 0;
		private var isMovingOut:Boolean = false;
		
		private var acceptAllFormat:Array = ["doorFormat", "windowFormat", "expandFormat", "openingFormat"];
		private var acceptChildFormat:Array = ["doorFormat", "windowFormat", "openingFormat"];
		
		// ruler 相关需要使用的数据
		private var rulerData:Vector.<Number>;
		private var rulerK:Number;
		
		// border 的绘图 Shape
		public var drawShape:Shape = new Shape();
		
		private var parentRoomBoundingBox:Rectangle;
		
		// 踢脚线相关变量
		public var skirtingSelectedColorID:int;
		public var skirtingSelectedSizeID:int;
		public var skirtingHostGoods:Goods;
		
		/////////////////////////////////////////////by zazisb 记录此边吸附关联的墙
		public var absorbRelatedBorder:Array;
		//////////////////////////////////////////////////////////
		
		public function RoomBorder(data:Vector.<Number>, index:int = -1, roomType:String = "room")
		{
			super(data, index);
			
			/////////////////////////////////////////////by zazisb 记录此边吸附关联的墙
			absorbRelatedBorder = new Array();
			//////////////////////////////////////////////////////////
			
			wallMap = ConstVariableInventory.wallBitmapData;
			this.hostGoods = ConstVariableInventory.initialWallGoods;
			this.selectedColorID = this.hostGoods.selectedColorID;
			this.selectedSizeID = this.hostGoods.selectedSizeID;
			
			skirtingMap = new BitmapData(2, 2, false, 0x999999);
			
			if (data.length > 4) isCurve = true;
			else isCurve = false;
			
			var solidFill:GraphicsSolidFill;
			if (roomType == "room")
			{
				solidFill = new GraphicsSolidFill(0x443d30);
				stroke = new GraphicsStroke(8, false, "normal", CapsStyle.SQUARE, JointStyle.MITER, 3, solidFill);
			}
			else if (roomType == "independentFloor")
			{
				solidFill = new GraphicsSolidFill(0xffff00);
				stroke = new GraphicsStroke(4, false, "normal", CapsStyle.SQUARE, JointStyle.MITER, 3, solidFill);
			}
			
			commands = new Vector.<int>();
			commands.push(GraphicsPathCommand.MOVE_TO);
			if (isCurve == false)
				commands.push(GraphicsPathCommand.LINE_TO);
			else commands.push(GraphicsPathCommand.CURVE_TO);
			
			k = MathCalculation.calculateGradient(data);
			
			addChild(drawShape);
			
			draw();
			
			// 设置图层混合样式
			this.blendMode = BlendMode.LAYER;
			
			this.addEventListener(DragEvent.DRAG_ENTER, roomBorderDragEnterHandler);
			this.addEventListener(DragEvent.DRAG_DROP, roomBorderDragDropHandler);
			this.addEventListener(DragEvent.DRAG_EXIT, roomBorderDragExitHandler);
			this.addEventListener(SetCompStateEvent.RESET_FILTER, resetFilterHandler);
		}
		
		/**
		 * 显示或隐藏 标尺
		 * 
		 */		
		public function showHideRuler():void
		{
			calculateRulerData();
			dispatchAddRulerEvent([this.parent.x + rulerData[0], this.parent.y + rulerData[1], this.parent.x + rulerData[data.length - 2], this.parent.y + rulerData[data.length - 1], rulerK, -1, "external"]);
			
			if (this.numChildren > 1)
				arrangeChildRuler();
		}
		
		public function resetFilterHandler(event:SetCompStateEvent):void
		{
			this.filters = null;
		}
		
		override public function changeSizeAndColor(picModel:PicModel, bitmapData:BitmapData = null, hostGoods:Goods = null):void
		{
			this.hostGoods = hostGoods;
			
			this.wallMap = bitmapData;
			
			if (picModel)
			{
				this.selectedColorID = picModel.selectedColorID;
				this.selectedSizeID = picModel.selectedSizeID;
			}
			else if (hostGoods)
			{
				this.selectedColorID = hostGoods.selectedColorID;
				this.selectedSizeID = hostGoods.selectedSizeID;
			}
		}
		
		public function changeSkirtingSizeAndColor(picModel:PicModel, bitmapData:BitmapData, hostGoods:Goods = null):void
		{
			this.skirtingHostGoods = hostGoods;
			
			this.skirtingMap = bitmapData;
			
			if (picModel)
			{
				this.skirtingSelectedColorID = picModel.selectedColorID;
				this.skirtingSelectedSizeID = picModel.selectedSizeID;
			}
			else if (hostGoods)
			{
				this.skirtingSelectedColorID = hostGoods.selectedColorID;
				this.skirtingSelectedColorID = hostGoods.selectedSizeID;
			}
		}
		
		private function calculateRulerData():void
		{
			if ((this.parent.rotation % 360) == 0)
			{
				rulerData = data;
				rulerK = k;
			}
			else
			{
				rulerData = new Vector.<Number>();
				
				for (var i:int = 0; i < data.length; i += 2)
				{
					var point:Point = MathCalculation.calculateOffsetPoint(new Point(data[i], data[i + 1]), this.parent.rotation);
					rulerData.push(point.x, point.y);
				}
				
				rulerK = (rulerData[rulerData.length - 1] - rulerData[1]) / (rulerData[rulerData.length - 2] - rulerData[0]);
			}
		}
		
		// 显示 BorderChild 的标尺
		private function arrangeChildRuler():void
		{
			var tempX:Number;
			var tempY:Number;
			var lastIndex:int = -1;
			
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if (this.getChildAt(i) is AbstractBorderChild)
				{
					lastIndex = i;
					var tempChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					if (i == 1)
					{
						dispatchAddRulerEvent([this.parent.x + data[0], this.parent.y + data[1], this.parent.x + tempChild.data[0], this.parent.y + tempChild.data[1], k, -1, "internal"]);
					}
					else
					{
						dispatchAddRulerEvent([this.parent.x + tempX, this.parent.y + tempY, this.parent.x + tempChild.data[0], this.parent.y + tempChild.data[1], k, -1, "internal"]);
					}
					dispatchAddRulerEvent([this.parent.x + tempChild.data[0], this.parent.y + tempChild.data[1], this.parent.x + tempChild.data[data.length - 2], this.parent.y + tempChild.data[data.length - 1], k, -1, "internal"]);
					
					tempX = tempChild.data[2];
					tempY = tempChild.data[3];
				}
			}
			
			if (lastIndex != -1)
				dispatchAddRulerEvent([this.parent.x + (this.getChildAt(lastIndex) as AbstractBorderChild).data[2], this.parent.y + (this.getChildAt(lastIndex) as AbstractBorderChild).data[3],
					this.parent.x + data[data.length - 2], this.parent.y + data[data.length - 1], k, -1, "internal"]);
		}
		
		private function dispatchAddRulerEvent(array:Array):void
		{
			if (this.parent is IndependentFloor || this.parent is InteriorWall) // zhangbo
			{
				array[0] += this.parent.parent.parent.x;
				array[1] += this.parent.parent.parent.y;
				array[2] += this.parent.parent.parent.x;
				array[3] += this.parent.parent.parent.y;
				
				if (array.length > 7)
				{
					array[7] += this.parent.parent.parent.x;
					array[8] += this.parent.parent.parent.y;
					array[9] += this.parent.parent.parent.x;
					array[10] += this.parent.parent.parent.y;
					array[14] += this.parent.parent.parent.x;
					array[15] += this.parent.parent.parent.y;
					array[16] += this.parent.parent.parent.x;
					array[17] += this.parent.parent.parent.y;
				}
			}
			
			this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.ADD_RULER, null, array));
		}
		
		/**
		 * 更新 ExternalRulerField 的位置和长度
		 * 
		 */		
		public function updateRuler(gridContainer:GridContainer):void
		{
			calculateRulerData();
			dispatchAddRulerEvent([this.parent.x + rulerData[0], this.parent.y + rulerData[1], this.parent.x + rulerData[rulerData.length - 2], this.parent.y + rulerData[rulerData.length - 1], rulerK, this.index, "external"]);
		}
		
		/**
		 * 显示 ExternalRulerField
		 * 
		 */		
		public function showRuler():void
		{
			calculateRulerData();
			dispatchAddRulerEvent([this.parent.x + rulerData[0], this.parent.y + rulerData[1], this.parent.x + rulerData[rulerData.length - 2], this.parent.y + rulerData[rulerData.length - 1], rulerK, -1, "external"]);
		}
		
		// 移动边框的时候修改 Door 的位置和倾斜角度
		private function changeChildPosition():void
		{
			// 重新设置该边框的斜率，用于计算 子孩子 的新顶点坐标
			k = MathCalculation.calculateGradient(data);
			
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					if (this.getChildAt(i) is AbstractBorderChild)
					{
						var child:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
						child.x = (data[2] - data[0]) * child.percentPosition + data[0];
						child.y = (data[3] - data[1]) * child.percentPosition + data[1];
							
						child.setRotation(data, k, new Point(child.x, child.y));
						
						// 如果 child 是 NormalDoor，且状态不是1，则重新设置它的状态
						if(child is NormalDoor && child.rotateState != 1)
						{
							this.changeDoorState(child);
						}
					}
				}
			}
		}
		
		// Expand Room 的时候，修改边框顶点之后，需要重置边框所有孩子的 percentPosition 属性
		private function changeChildPercentPosition():void
		{
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var child:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					child.percentPosition = Math.sqrt((child.x - data[0]) * (child.x - data[0]) + (child.y - data[1]) * (child.y - data[1]))
						/ Math.sqrt((data[2] - data[0]) * (data[2] - data[0]) + (data[3] - data[1]) * (data[3] - data[1]));
				}
			}
		}
		
		/////////////////////////////////by zazisb 获取边上一段范围内所包含的borderchild
		public function findChildInBoundry(boundry:Rectangle):Array
		{
			var array:Array = new Array();
			
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var borderChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					var point1:Point = MathCalculation.transExPtFromInPt(borderChild, new Point(borderChild.data[0], borderChild.data[1]));
					var point2:Point = MathCalculation.transExPtFromInPt(borderChild, new Point(borderChild.data[2], borderChild.data[3]));
					
					if(boundry.contains(point1.x, point1.y)
						&& boundry.contains(point2.x, point2.y))
						array.push(borderChild);
				}
			}
			
			return array;
		}
		///////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////by zazisb 获取边上shared并且sharedborder为特定border的child
		public function findChildShared(border:RoomBorder):Array
		{
			var array:Array = new Array();
			
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var borderChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					if((borderChild.borrowed || borderChild.shared) && borderChild.sharedBorder == border)
					{
						if(borderChild is NormalDoor ||borderChild is NormalWindow)
							array.push(borderChild);
					}
				}
			}
			
			return array;
		}
		///////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////by zazisb 获取边上borrowed并且sharedborder为特定border的child
		public function findChildBorrowed(border:RoomBorder):Array
		{
			var array:Array = new Array();
			
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var borderChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					if(borderChild.borrowed && borderChild.sharedBorder == border)
						array.push(borderChild);
				}
			}
			
			return array;
		}
		///////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////by zazisb 还原边上share的属性的child
		public function recoveSharedChild(border:RoomBorder):void
		{
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var borderChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					if((borderChild.shared) && borderChild.sharedBorder == border)
					{
						borderChild.shared = false;
						
						if(borderChild is OpeningWall)
							(borderChild as OpeningWall).oppositeWall = null;
					}
				}
			}
		}
		///////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////by zazisb 删除fake属性的child
		public function removeFakeChild(border:RoomBorder):void
		{
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					var borderChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					if((borderChild.fake) && borderChild.sharedBorder == border)
					{
						this.removeChild(borderChild);
						i--;
					}
				}
			}
		}
		///////////////////////////////////////////////////////////////////////////////////////
		
		
		private function removeOutsideChild(x:Number, y:Number):void
		{
			if (this.numChildren != 1)
			{
				for (var i:int = 1; i < this.numChildren; i++)
				{
					if (this.getChildAt(i) is AbstractBorderChild)
					{
						var child:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
						if (MathCalculation.isInMiddlePosition(data[0], data[1], x, y, child.x, child.y))
							removeChildVector.push(child);
					}
				}
			}
		}
		
		override public function resetData(offsetX:Number, offsetY:Number):void
		{
			super.resetData(offsetX, offsetY);
			changeChildPosition();
		}
		
		/**
		 * 清空 removeChildVector 临时向量数组，并重置 childCount
		 * Expand Room 的时候可能需要用到
		 */		
		public function clearRemoveChildVector():void
		{
			removeChildVector = new Vector.<AbstractBorderChild>();
		}
		
		/**
		 * Expand Room 的时候，有时候需要增加一些子孩子
		 * @param addChildVector 需要添加到显示列表中的子孩子向量数组
		 * 
		 */		
		public function addNewChild(addChildVector:Vector.<AbstractBorderChild>):void
		{
			for each (var borderChild:AbstractBorderChild in addChildVector)
			{
				this.addChild(borderChild);
			}
			changeChildPercentPosition();
		}
		
		/**
		 * Expand Room 的时候需要重置第一个顶点，并且修改所有子孩子的 percentPosition 属性
		 * @param x 重置第一个顶点的 X 轴坐标
		 * @param y 重置第一个顶点的 Y 轴坐标
		 * 
		 */		
		public function moveFirstVertex(x:Number, y:Number):void
		{
			data[0] = x;
			data[1] = y;
			draw();
			changeChildPercentPosition();
		}
		
		/**
		 * Expand Room 的时候需要重置最后一个顶点，并且修改所有子孩子的 percentPosition 属性
		 * @param x 重置最后一个顶点的 X 轴坐标
		 * @param y 重置最后一个顶点的 Y 轴坐标
		 * 
		 */
		public function moveLastVertex(x:Number, y:Number):void
		{
			data[2] = x;
			data[3] = y;
			draw();
			changeChildPercentPosition();
		}
		
		/**
		 * 修改该边框第一个顶点的坐标值并重绘
		 * @param offsetX X轴偏移量
		 * @param offsetY Y轴偏移量
		 * 
		 */		
		public function resetFirstData(offsetX:Number, offsetY:Number):void
		{
			data[0] += offsetX;
			data[1] += offsetY;
			draw();
			changeChildPosition();
		}
		
		/**
		 * 修改该边框最后个顶点的坐标值并重绘
		 * @param offsetX X轴偏移量
		 * @param offsetY Y轴偏移量
		 * 
		 */
		public function resetLastData(offsetX:Number, offsetY:Number):void
		{
			data[data.length - 2] += offsetX;
			data[data.length - 1] += offsetY;
			draw();
			changeChildPosition();
		}
		
		/**
		 * 修改该边框中间顶点的坐标值并重绘，用于弧形边框
		 * @param offsetX X轴偏移量
		 * @param offsetY Y轴偏移量
		 * 
		 */
		public function resetMiddleData(offsetX:Number, offsetY:Number):void
		{
			data[2] += offsetX;
			data[3] += offsetY;
			draw();
		}
		
		public function isChildCollision():Boolean
		{
			var firstChild:AbstractBorderChild;
			
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if (this.getChildAt(i) is AbstractBorderChild)
				{
					if (i == 1)
						firstChild = this.getChildAt(1) as AbstractBorderChild;
					else
					{
						if (CollisionDetection.complexHitTestObject(this.getChildAt(i), firstChild))
							return true;
						else
							firstChild = this.getChildAt(i) as AbstractBorderChild;
					}
				}
			}
			
			return false;
		}
		
		override protected function draw():void
		{
			//this.graphics.clear();
			this.drawShape.graphics.clear();
			var path:GraphicsPath = new GraphicsPath(commands, data);
			
			graphicsData = new Vector.<IGraphicsData>();
			graphicsData.push(stroke);
			graphicsData.push(path);
			
			//this.graphics.drawGraphicsData(graphicsData);
			this.drawShape.graphics.drawGraphicsData(graphicsData);
		}
		
		private function roomBorderDragEnterHandler(event:DragEvent):void
		{
			if (!isCurve && !(this.parent is IndependentFloor) && !(this.parent is InteriorWall) && acceptAllFormat.indexOf(event.dragSource.formats[0]) != -1)
			{
				DragManager.acceptDragDrop(IUIComponent(event.currentTarget));
				this.addEventListener(DragEvent.DRAG_OVER, roomBorderDragOverHandler);
			}
		}
		
		private function roomBorderDragOverHandler(event:DragEvent):void
		{
			var format:String = event.dragSource.formats[0];
			if (acceptChildFormat.indexOf(format) != -1)
			{
				var dragBorderChild:AbstractBorderChild = event.dragSource.dataForFormat(format) as AbstractBorderChild;
				
				var pedalPoint:Point = MathCalculation.getPedalPoint(k, data, new Point(this.contentMouseX, this.contentMouseY));
				
				k = MathCalculation.calculateGradient(data);
				dragBorderChild.setRotation(data, k, pedalPoint);
				
				if (!isCollisionWithOthers(dragBorderChild))
				{
					dragBorderChild.removeFilter();
					showOverInteriorRuler(dragBorderChild, pedalPoint);
				}
				else
				{
					// 门、窗、开放墙 碰撞后 隐藏 标尺
					this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS));
				}
			}
		}
		
		public function showOverInteriorRuler(dragBorderChild:AbstractBorderChild, pedalPoint:Point):void
		{
			var tempX:Number = data[0];
			var tempY:Number = data[1];
			
			var lastChildIndex:int = -1;
			
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if (this.getChildAt(i) is AbstractBorderChild && this.getChildAt(i) != dragBorderChild)
				{
					lastChildIndex = i;
					
					var tempChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					var rectangle:Rectangle = MathCalculation.getRectangleByTwoPoint(data[0], data[1], tempChild.data[0], tempChild.data[1]);
					
					if (rectangle.containsPoint(pedalPoint))
					{
						addInternalRulerField(tempX, tempY, dragBorderChild, tempChild.data[0], tempChild.data[1]);
						return;
					}
					else
					{
						tempX = tempChild.data[2];
						tempY = tempChild.data[3];
					}
				}
			}
			
			if (lastChildIndex == -1)
				addInternalRulerField(data[0], data[1], dragBorderChild, data[2], data[3]);
			else
				addInternalRulerField((this.getChildAt(lastChildIndex) as AbstractBorderChild).data[2], (this.getChildAt(lastChildIndex) as AbstractBorderChild).data[3], dragBorderChild, data[2], data[3]);
		}
		
		private function addInternalRulerField(p1X:Number, p1Y:Number, dragBorderChild:AbstractBorderChild, p2X:Number, p2Y:Number):void
		{
			dispatchAddRulerEvent([this.parent.x + p1X, this.parent.y + p1Y, this.parent.x + dragBorderChild.data[0], this.parent.y + dragBorderChild.data[1], k, this.index, "internal",
				this.parent.x + dragBorderChild.data[0], this.parent.y + dragBorderChild.data[1], this.parent.x + dragBorderChild.data[2], this.parent.y + dragBorderChild.data[3], k, this.index, "internal",
					this.parent.x + dragBorderChild.data[2], this.parent.y + dragBorderChild.data[3], this.parent.x + p2X, this.parent.y + p2Y, k, this.index, "internal"]);
		}
		
		public function dragAddChild(child:AbstractBorderChild):void
		{
			this.addChild(child);
		}
		
		public function dragRemoveChild(child:AbstractBorderChild):void
		{
			this.removeChild(child);
		}
		
		/**
		 * 清空所有子孩子的滤镜
		 * 
		 */		
		public function clearAllChildFilter():void
		{
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if (this.getChildAt(i) is AbstractBorderChild)
					(this.getChildAt(i) as AbstractBorderChild).removeFilter();
			}
		}
		
		/**
		 * 判断当前 hostChild 是否发生碰撞或者出界
		 * @param host 当前需要判断是否碰撞或者出界的 BorderChild
		 * @return 是否发生碰撞或者出界
		 * 
		 */		
		public function isCollisionWithOthers(host:AbstractBorderChild):Boolean
		{
			clearAllChildFilter();
			
			collisionCount = 0;
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if ((this.getChildAt(i) != host) && CollisionDetection.complexHitTestObject(this.getChildAt(i), host))
				{
					(this.getChildAt(i) as AbstractBorderChild).addFilter();
					collisionCount++;
				}
			}
			
			if (collisionCount == 0)
			{
				var rectangle:Rectangle = MathCalculation.getRectangleByTwoPoint(data[0], data[1], data[2], data[3]);
				
				if (rectangle.contains(host.data[2], host.data[3]))
				{
					isMovingOut = false;
					return false;
				}
				else
				{
					isMovingOut = true;
					host.addFilter();
					return true;
				}
			}
			else
			{
				host.addFilter();
				return true;
			}
		}
		
		// 添加 borderChild 之后，重新 borderChild 的 index
		public function changeChildIndex(host:AbstractBorderChild):void//by zazisb 改为public
		{
			for (var i:int = 1; i < this.numChildren; i++)
			{
				if (this.getChildAt(i) is AbstractBorderChild && (this.getChildAt(i) != host))
				{
					var tempChild:AbstractBorderChild = this.getChildAt(i) as AbstractBorderChild;
					
					var rectangle:Rectangle = MathCalculation.getRectangleByTwoPoint(data[0], data[1], tempChild.data[0], tempChild.data[1]);
					
					if (rectangle.contains(host.data[0], host.data[1]))
					{
						this.setChildIndex(host, i);
						break;
					}
				}
			}
		}
		
		/**
		 * 删除边框
		 * 即添加等长的 OpeningWall
		 */		
		public function deleteBorder():void
		{
			var firstPoint:Point = Point.interpolate(new Point(data[0], data[1]), new Point(data[data.length - 2], data[data.length - 1]), 0.98);
			var secondPoint:Point = Point.interpolate(new Point(data[0], data[1]), new Point(data[data.length - 2], data[data.length - 1]), 0.02);
			
			var openingWall:OpeningWall = new OpeningWall(Point.distance(firstPoint, secondPoint));
			openingWall.blendMode = BlendMode.ERASE;
			openingWall.x = firstPoint.x;
			openingWall.y = firstPoint.y;
			openingWall.setRotation(data, k, firstPoint);
			openingWall.percentPosition = Point.distance(new Point(data[0], data[1]), firstPoint) / Point.distance(new Point(data[0], data[1]), new Point(data[data.length - 2], data[data.length - 1]));
			openingWall.parentBorder = this;
			
			addChild(openingWall);
			
			(this.parent as AbstractDrawingRoom).hideVertex();
		}
		
		private function roomBorderDragDropHandler(event:DragEvent):void
		{
			// 隐藏标尺
			this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS));
			
			if (collisionCount != 0 || isMovingOut)
			{
				clearAllChildFilter();
			}
			else
			{
				var x:Number;
				var y:Number;
				
				k = MathCalculation.calculateGradient(data);
				var pedalPoint:Point = MathCalculation.getPedalPoint(k, data, new Point(this.contentMouseX, this.contentMouseY));
				x = pedalPoint.x;
				y = pedalPoint.y;
				
				var format:String = event.dragSource.formats[0];
				if (acceptChildFormat.indexOf(format) != -1)
				{
					var borderChild:AbstractBorderChild = event.dragSource.dataForFormat(format) as AbstractBorderChild;
					borderChild.scaleX = 1;
					borderChild.scaleY = 1;
					event.currentTarget.addChild(borderChild);
					borderChild.parentBorder = this;
					
					borderChild.x = x;
					borderChild.y = y;
					
					borderChild.setRotation(data, k, pedalPoint);
					
					borderChild.percentPosition = Math.sqrt((x - data[0]) * (x - data[0]) + (y - data[1]) * (y - data[1]))
						/ Math.sqrt((data[2] - data[0]) * (data[2] - data[0]) + (data[3] - data[1]) * (data[3] - data[1]));
					
					if (event.dragSource.hasFormat('openingFormat'))
					{
						borderChild.blendMode = BlendMode.ERASE;
					}
					
					// 将该边框的孩子按顺序排列 index
					changeChildIndex(borderChild);
					
					// 如果拖拽的是 NormalDoor，显示 RotaionBtn
					if(borderChild is NormalDoor)
					{
						borderChild.showRotationBtn(); 
					}
					
					/////////////////////////////////////////by zazisb dragdrop后处理吸附
					AbsorptionDetection.DoAbsorption(this, true, borderChild);
				}
				else if (event.dragSource.hasFormat('expandFormat'))
				{
					var newData:Vector.<Number> = new Vector.<Number>();
					
					var point:Point = MathCalculation.getOffsetValue(k, ConstVariableInventory.EXPAND_WALL_LENGTH, data);
					
					switch (event.dragSource.dataForFormat('expandFormat'))
					{
						case "assets/images/curvedWall.png":
							removeOutsideChild(x, y);
							
							newData.push(x, y);
							newData.push(x + (point.x + point.y) / 2, y + (point.y - point.x) / 2);
							newData.push(x + point.x, y + point.y);
							event.target.parent.expandRoom(newData, this, "curved");
							break;
						case "assets/images/squareWall.png":
							removeOutsideChild(x, y);
							
							newData.push(x, y);
							newData.push(x + point.y, y - point.x);
							newData.push(x + point.x + point.y, y - point.x + point.y);
							newData.push(x + point.x, y + point.y);
							event.target.parent.expandRoom(newData, this);
							break;
						case "assets/images/angledWall.png":
							removeOutsideChild(x, y);
							
							var offsetX:Number = 15 / Math.sqrt(k * k + 1);
							var offsetY:Number = offsetX * k;
							
							newData.push(x, y);
							
							if (k > 0 && k != Infinity)
							{
								if (data[3] > data[1])
								{
									newData.push(x + point.y + offsetX, y - point.x + offsetY);
									newData.push(x + point.x + point.y - offsetX, y - point.x + point.y - offsetY);
								}
								else
								{
									newData.push(x + point.y - offsetX, y - point.x - offsetY);
									newData.push(x + point.x + point.y + offsetX, y - point.x + point.y + offsetY);
								}
							}
							else if (k < 0)
							{
								if (data[3] > data[1])
								{
									newData.push(x + point.y - offsetX, y - point.x - offsetY);
									newData.push(x + point.x + point.y + offsetX, y - point.x + point.y + offsetY);
								}
								else
								{
									newData.push(x + point.y + offsetX, y - point.x + offsetY);
									newData.push(x + point.x + point.y - offsetX, y - point.x + point.y - offsetY);
								}
							}
							else if (k == 0)
							{
								if (data[2] > data[0])
								{
									newData.push(x + point.y + 15, y - point.x);
									newData.push(x + point.x + point.y - 15, y - point.x + point.y);
								}
								else
								{
									newData.push(x + point.y - 15, y - point.x);
									newData.push(x + point.x + point.y + 15, y - point.x + point.y);
								}
							}
							else
							{						
								if (data[3] > data[1])
								{
									newData.push(x + point.y, y - point.x + 15);
									newData.push(x + point.x + point.y, y - point.x + point.y - 15);
								}
								else
								{
									newData.push(x + point.y, y - point.x - 15);
									newData.push(x + point.x + point.y, y - point.x + point.y + 15);
								}
							}
							newData.push(x + point.x, y + point.y);
							event.target.parent.expandRoom(newData, this);
							break;	
						case "assets/images/lShapedWall.png":
							var leftDistance:Number = (data[0] - x) * (data[0] - x) + (data[1] - y) * (data[1] - y);
							var rightDistance:Number = (data[2] - x) * (data[2] - x) + (data[3] - y) * (data[3] - y);
							
							if (leftDistance <= rightDistance)
							{
								newData.push(data[0] + point.y, data[1] - point.x);
								newData.push(data[0] + point.x + point.y, data[1] - point.x + point.y);
								newData.push(data[0] + point.x, data[1] + point.y);
								event.target.parent.expandRoom(newData, this, "left");
							}
							else
							{
								newData.push(data[2] - point.x, data[3] - point.y);
								newData.push(data[2] - point.x + point.y, data[3] - point.y - point.x);
								newData.push(data[2] + point.y, data[3] - point.x);
								event.target.parent.expandRoom(newData, this, "right");
							}
							break;	
					}
				}
			}
		}
		
		private function roomBorderDragExitHandler(event:DragEvent):void
		{
			// 隐藏标尺
			this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS));
			
			clearAllChildFilter();
			
			this.removeEventListener(DragEvent.DRAG_OVER, roomBorderDragOverHandler);
			
			var format:String = event.dragSource.formats[0];
			if (acceptChildFormat.indexOf(format) != -1)
			{
				var borderChild:AbstractBorderChild = event.dragSource.dataForFormat(format) as AbstractBorderChild;
				borderChild.removeFilter();
				borderChild.rotation = 0;
			}
		}
		
		override protected function mouseOverHandler(event:MouseEvent):void
		{
			super.mouseOverHandler(event);
			
			// 更改光标
			changeCursor();
		}
		
		override protected function mouseMoveHandler(event:MouseEvent):void
		{
			super.mouseMoveHandler(event);
			
			updateCursor();
		}
		
		override protected function mouseOutHandler(event:MouseEvent):void
		{
			super.mouseOutHandler(event);
			
			// 移除光标
			dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.HIDE_CUSTOM_CURSOR, 0, 0));
		}
		
		override protected function mouseDownHandler(event:MouseEvent):void
		{
			////////////////////by zazisb
			AbsorptionDetection.CancelAbsorption(this);
			// 隐藏 InfoWindow
			this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW));
			this.dispatchEvent(new ShowHideFilterEvent(ShowHideFilterEvent.HIDE_FILTER, this));
			this.dispatchEvent(new SetCompStateEvent(SetCompStateEvent.RESET_FILTER));
			this.filters = null;
			// 隐藏 RoomName
			this.dispatchEvent(new RoomNameAdminEvent(RoomNameAdminEvent.HIDE_ROOM_NAME));
			
			if (!(this.parent is IndependentFloor) && !(this.parent is InteriorWall))
				this.dispatchEvent(new ShowVertexEvent(ShowVertexEvent.SHOW_VERTEX, this));
			else
				(this.parent as AbstractDrawingRoom).showVertex(this);
			
			// 获取父房间类包围盒
			if (this.parent is InteriorWall || this.parent is IndependentFloor)
			{
				if (this.parent.parent.parent is AbstractDrawingRoom)
					parentRoomBoundingBox = (this.parent.parent.parent as AbstractDrawingRoom).updateBoundingAndCenterPoint();
			}
			
			super.mouseDownHandler(event);
			
			// 移除场景中的 rotationBtn
			if (!(this.parent is InteriorWall))
			{
				this.dispatchEvent(new RotationRelatedEvent(RotationRelatedEvent.HIDE_ROTATION_BTN));
			}
			
			// 隐藏标尺
			this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS, this.parent as AbstractDrawingRoom));
			
			// 关闭 GridContainer 的 mouseChildren 属性
			this.dispatchEvent(new MouseEnabledAdminEvent(MouseEnabledAdminEvent.MOUSE_ENABLED_CLOSED));
			
			calculateRulerData();
		}
		
		override protected function enterFrameHandler(event:Event):void
		{
			// 隐藏 InfoWindow
			this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW));
			this.dispatchEvent(new ShowHideFilterEvent(ShowHideFilterEvent.HIDE_FILTER, this));
			this.dispatchEvent(new SetCompStateEvent(SetCompStateEvent.RESET_FILTER));
			this.filters = null;
			
			super.enterFrameHandler(event);
			
			calculateRulerData();
			
			var tempOffsetX:Number = 0;
			var tempOffsetY:Number = 0;
			
			if (this.parent is InteriorWall)
			{
				(this.parent as AbstractDrawingRoom).moveBorder(offsetX, offsetY, this);
				tempOffsetX = offsetX;
				tempOffsetY = offsetY;
			}
			else
			{
				var point:Point;
				if (rulerK == 0 || Math.abs(rulerK) < 1)
				{
					point = MathCalculation.calculateOffsetPoint(new Point(0, offsetY), -this.parent.rotation);
				}
				else if (rulerK == Infinity || Math.abs(rulerK) >= 1)
				{
					point = MathCalculation.calculateOffsetPoint(new Point(offsetX, 0), -this.parent.rotation);
				}
				(this.parent as AbstractDrawingRoom).moveBorder(point.x, point.y, this);
				tempOffsetX = point.x;
				tempOffsetY = point.y;
			}
			
			if (!(this.parent is IndependentFloor) && !(this.parent is InteriorWall))
			{
				if (CollisionDetection.isCollision(this)
					|| (this.parent as AbstractDrawingRoom).isBorderChildCollisionByBorder(this)
					|| MathCalculation.isRoomOverTurn((this.parent as AbstractDrawingRoom).vertices))
				(this.parent as AbstractDrawingRoom).moveBorder(-tempOffsetX, -tempOffsetY, this);
			}
			else if ((this.parent is IndependentFloor || this.parent is InteriorWall) && (this.parent.parent.parent is AbstractDrawingRoom))
			/*else if ((this.parent is IndependentFloor ) && (this.parent.parent.parent is AbstractDrawingRoom))*/

			{
				//if (CollisionDetection.isCollisionWithOther(this.parent as UIComponent)
				if (CollisionDetection.isCollisionWithOther(this)
					|| ((this.parent.parent.parent as AbstractDrawingRoom).updateBoundingAndCenterPoint().width != parentRoomBoundingBox.width)
					|| ((this.parent.parent.parent as AbstractDrawingRoom).updateBoundingAndCenterPoint().height != parentRoomBoundingBox.height))
					(this.parent as AbstractDrawingRoom).moveBorder(-tempOffsetX, -tempOffsetY, this);
			}
			/*else if ((this.parent is InteriorWall) && (this.parent.parent.parent is AbstractDrawingRoom))
			{
				//if (CollisionDetection.isCollisionWithOther(this.parent as UIComponent)
				if (CollisionDetection.isCollisionWithInteriorWall(this)
					|| ((this.parent.parent.parent as AbstractDrawingRoom).updateBoundingAndCenterPoint().width != parentRoomBoundingBox.width)
					|| ((this.parent.parent.parent as AbstractDrawingRoom).updateBoundingAndCenterPoint().height != parentRoomBoundingBox.height))
					(this.parent as AbstractDrawingRoom).moveBorder(-tempOffsetX, -tempOffsetY, this);
			}*/
			
			// 更改光标
			updateCursor();
		}
		
		override protected function mouseUpHandler(event:MouseEvent):void
		{
			super.mouseUpHandler(event);
			
			// 隐藏标尺
			this.dispatchEvent(new RulerAdminEvent(RulerAdminEvent.HIDE_ALL_RULERS));
			
			// 显示 InfoWindow
			if (!(this.parent is IndependentFloor))
			{
				dispatchShowInfoEvent();
				this.dispatchEvent(new ShowHideFilterEvent(ShowHideFilterEvent.SHOW_FILTER, this));
			}
			
		/*	var glowFilter:GlowFilter=new GlowFilter(0xffff00,1,8,8,3,1,false,false);
			//创建滤镜数组,通过将滤镜作为参数传递给Array()构造函数,
			//将该滤镜添加到数组中
			var filtersArray:Array=new Array(glowFilter);*/
			//将滤镜数组分配给显示对象以便应用滤镜
			//this.filters=[new spark.filters.GlowFilter(0xffff00,1,8,8,3,1,false,false)];
			
			// 移除光标
			dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.HIDE_CUSTOM_CURSOR, 0, 0));
			
			// 开启 GridContainer 的 mouseChildren 属性
			this.dispatchEvent(new MouseEnabledAdminEvent(MouseEnabledAdminEvent.MOUSE_ENABLED_OPENED));
			//////////////////////////by zazisb 吸附
			AbsorptionDetection.DoAbsorption(this);
			
			
		}
		
		private function changeCursor():void
		{
			var pedalPoint:Point = MathCalculation.getPedalPoint(k, data, new Point(this.contentMouseX, this.contentMouseY));
			if (k == 0 || Math.abs(k) < 1)
			{
				if (this.parent is IndependentFloor || this.parent is InteriorWall)
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR, this.parent.parent.parent.x + this.parent.x + pedalPoint.x, this.parent.parent.parent.y + this.parent.y + pedalPoint.y, "horizontal"));
				else
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR, this.parent.x + pedalPoint.x, this.parent.y + pedalPoint.y, "horizontal"));
			}
			else if (k == Infinity || Math.abs(k) >= 1)
			{
				if (this.parent is IndependentFloor)
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR, this.parent.parent.parent.x + this.parent.x + pedalPoint.x, this.parent.parent.parent.y + this.parent.y + pedalPoint.y, "vertical"));
				else
					dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.SHOW_CUSTOM_CURSOR, this.parent.x + pedalPoint.x, this.parent.y + pedalPoint.y, "vertical"));
			}
		}
		
		override public function moveShape(xOffset:Number = 0, yOffset:Number = 0):Boolean
		{
			if (this.parent is InteriorWall)
			{
				this.parent.x += xOffset;
				this.parent.y += yOffset;
				
				if (CollisionDetection.isCollisionWithOther(this.parent as InteriorWall))
				{
					(this.parent).x -= xOffset;
					(this.parent).y -= yOffset;
					return false;
				}
				else
					return true;
			}
			
			return false;
		}
		
		private function updateCursor():void
		{
			var pedalPoint:Point;
			if (this.parent is IndependentFloor || this.parent is InteriorWall)
			{
				pedalPoint = MathCalculation.getPedalPoint(k, data, new Point(this.contentMouseX, this.contentMouseY));
				dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.UPDATE_CUSTOM_CURSOR, this.parent.parent.parent.x + this.parent.x + pedalPoint.x, this.parent.parent.parent.y + this.parent.y + pedalPoint.y));
			}
			else
			{
				pedalPoint = MathCalculation.getPedalPoint(k, data, new Point(this.contentMouseX, this.contentMouseY));
				dispatchEvent(new CursorBitmapEvent(CursorBitmapEvent.UPDATE_CUSTOM_CURSOR, this.parent.x + pedalPoint.x, this.parent.y + pedalPoint.y));
			}
		}
		
		private function changeDoorState(child:AbstractBorderChild):void
		{
			var tmpPoint:Point = MathCalculation.getOffsetValue(((child.parent) as RoomBorder).k, child.length, ((child.parent) as RoomBorder).data);
			var ObState:int = child.rotateState;
			var revRotate:Number = (child as NormalDoor).getReverseRotation((child as AbstractBorderChild).data, ((child.parent) as RoomBorder).k);
			var segFlag:Boolean = (child as AbstractBorderChild).segFlag;
			
			child.transformNormalDoorState(tmpPoint, revRotate, ObState);
		}
		
		private function dispatchShowInfoEvent():void
		{
			var firstPoint:Point;
			var windowPoint:Point;
			
			if (this.parent is InteriorWall)
				firstPoint = new Point((data[0] + data[2]) / 2 + this.parent.x + this.parent.parent.parent.x, (data[1] + data[3]) / 2 + this.parent.y + this.parent.parent.parent.y);
			else
				firstPoint = new Point((data[0] + data[2]) / 2 + this.parent.x, (data[1] + data[3]) / 2 + this.parent.y);
			
			var secondPoint:Point = new Point(firstPoint.x + 80, firstPoint.y - 80);
			
			if (this.parent is InteriorWall)
				windowPoint = this.parent.parent.parent.parent.localToGlobal(secondPoint);
			else
				windowPoint = this.parent.parent.localToGlobal(secondPoint);
			
			this.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.SHOW_TITLE_WINDOW,
				firstPoint.x, firstPoint.y,
				secondPoint.x, secondPoint.y,
				windowPoint.x, windowPoint.y,
				this));
		}
	}
}